fix(orchestrator): Expose pending delegated child work - #4793
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR adds a new feature exposing pending child work state ( You can customize Macroscope's approvability policy. Learn more. |
e1056de to
4df5866
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4df5866. Configure here.
a6f4edd to
e87ea74
Compare
Co-authored-by: codex <codex@users.noreply.github.com>
- Initialize provider as unchecked in a pending state - Update initial probe message to reflect session-local status
- Type the runtime effect with `Scope` - Build the ACP session runtime without wrapping it in `Effect.scoped`
- Use strict TurnId and ProviderItemId parsing in Codex session routing - Decode in-memory stdio chunks in streaming mode to avoid split UTF-8 corruption
- Transfer session-owned scopes into adapter state - Ensure runtime scopes close on stop and startup failure - Add regression coverage for scoped lifecycle cleanup
- Close the managed native event logger when the adapter layer tears down - Make session runtime close idempotent with an atomic closed flag - Add coverage for flushing thread native logs on shutdown
- Use codex app-server snapshots for auth, models, and skills - Remove legacy CLI/config discovery paths and related helpers - Update tests for the new provider status flow
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
- Document the target orchestration graph, IDs, lifecycles, and capability model - Add Codex app-server probe fixtures and update the probe test harness
- Introduce orchestration v2 service interfaces and error types - Add replay runtime, fixtures, and integration coverage - Update shared contracts and probe transcripts Co-authored-by: codex <codex@users.noreply.github.com>
- Add Codex adapter and replay harness wiring - Introduce in-memory orchestration projections and provider registry - Expand orchestration contracts for turn and runtime events
Co-authored-by: codex <codex@users.noreply.github.com>
Distinguish queued and steering user messages in the mobile thread feed, matching the web timeline. Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
- Publish migration lifecycle events during startup - Show a web toast while legacy threads are restored
- Project retry progress and recovery for Codex and Claude turns - Sync thread completion markers through server-side visit timestamps
…4963) Co-authored-by: codex <codex@users.noreply.github.com>
… compaction (pingdotgg#4971) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Disable LegendList end-maintenance that could snap after user scrolling - Cancel stale imperative scrolls and release settled turn anchors - Stabilize handoff run data to avoid per-event timeline rerenders
…elay Live profiling of the built app (debugger pause inside the hot sqlite call) showed AgentAwarenessRelay.publishThread grinding at ~8 full shell snapshots per second after boot. Two causes: - streamDomainEvents was eventSink.stream() with no cursor, which replays every stored event from genesis before going live — so each boot fed the relay the entire event history as fresh activity, and it queued a publish per activity-relevant event for hours. It now tails from the current high-water mark; the relay's startup snapshot publish already covers initial state, and the sink subscribes before reading the cursor so no live event is lost. - publishThreadUnsafe materialized the full shell snapshot to find one thread; it now uses getThreadShell (archived/deleted map to the tombstone path exactly as the active-list lookup did). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A renderer performance trace showed the minimap strips as a standing source of main-thread frame work: each strip transitioned background-color (paint) and width (layout), and both fire constantly — scrolling or streaming flips a band of in-view states at once, and the hover fisheye animates several widths at a time — so any interaction kept a 60fps style/layout/paint pipeline running. The strip now animates only compositor-friendly properties: width tiers are scale-x on a fixed-width box, and the in-view highlight is a bright overlay faded with opacity. The scroll handler also skips no-op data-in-view attribute writes, which previously re-dirtied style state for every strip on every scroll tick. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follow-ups from the main merge: - Migration numbering: main's 035_ProjectionThreadTitleRegeneration is released and keeps its id; this branch's unreleased v2 migrations shift to 036-044 instead (a released migration can never be renumbered). - thread.metadata.update accepts regenerateTitle: true arms an in-flight titleRegeneration marker on the thread payload (requestId + startedAt), a landing title or explicit false clears it. The marker projects onto thread shells and through the client-runtime shell model, so the sidebar's Regenerating state works unchanged. - New ThreadTitleRegenerationService worker reacts to armed markers on the live domain-event stream (so ws, MCP, and mobile dispatches all behave the same): builds a newest-first conversation digest from the v2 projection (8k-char budget, retained attachments — ported from the v1 reactor), generates via TextGeneration, and lands the title with a follow-up metadata update. Failures clear the marker and log. - The server advertises threadTitleRegeneration again, and the client updateThreadMetadata dispatches regenerateTitle-only updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The turn item materialized when a queued run is promoted was emitted with inputIntent "turn_start", but the deterministic replay driver (and the recorded queued_turn fixtures) expect "queued_turn" — the mismatch stalled replay before the queued run could start, leaving run 1 waiting and run 2 queued forever in all five queued_turn fixtures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Effect service conventions: ThreadManagementThreadNotSendableError carried an Archived/NoSteerableRun reason union and switched on reason._tag inside the message getter. Modelled as two error classes (ThreadManagementThreadArchivedError, ThreadManagementNoSteerableRunError); both still map to the MCP thread_not_sendable failure code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Prevent the title row from shifting when output is revealed - Preserve panel and compact button sizing
a543fd4 to
378615b
Compare
e87ea74 to
b73f59d
Compare
c5e53c8 to
922f352
Compare

Summary
Expose whether a delegated child thread has later work pending without changing
the established meaning of the original delegation fields.
childRunId,status,summary, andresultContextTransferIdstay tied tothe original
delegate_taskrun. NewhasPendingChildRunsandlatestTerminal*fields let callers avoid treating a busy child as idle andinspect its newest meaningful terminal result.
This replaces the earlier broader implementation. The branch no longer changes
current-run selection, per-follow-up result finalization, wake policy, or
task_cancelbehavior.Problem and Fix
task_statusintentionally reported the original delegated run, but provided no indication that the same child thread had a queued or executing follow-up. A caller could seecompletedand act on a workspace the child was still changing.hasPendingChildRuns, derived from nonterminal runs with a later ordinal than the delegated run, while preserving the original delegation fields.latestTerminalRunId,latestTerminalStatus,latestTerminalSummary, andlatestTerminalResultContextTransferId. Rolled-back runs and never-started later cancellations do not displace a meaningful result.subagent_spawntransfer selected the latest child run as the delegated run, which could hide later active work.Validation
passes: cancelling a completed original task does not interrupt a later child
run.
STATUS_FIRST_DONE.hasPendingChildRunswas true, and the latest terminal result stayed onordinal 1.
STATUS_SECOND_DONE, pending became falseand
latestTerminalRunIdadvanced to ordinal 2 while primary fieldsremained unchanged.
Bugbot, and Macroscope Effect Service Conventions pass.
newer
t3code/codex-turn-mappingmerge result. Check is separately red fromthe known Vite+ stdout panic while printing warnings.
Checklist
Note
Medium Risk
Extends the orchestrator MCP contract and changes legacy delegated-run selection; impact is limited to delegated-task observability and does not alter auth, cancellation, or wake policy.
Overview
Delegated
task_status/delegate_taskresults now expose follow-up child activity without redefining the original delegation fields.childRunId,status,summary, andresultContextTransferIdstill describe the original delegated run;hasPendingChildRunssignals queued or running child runs with a higher ordinal, andlatestTerminal*fields surface the newest meaningful terminal child run (excluding rolled-back and never-started cancellations).delegatedTaskRunfor legacy projections without asubagent_spawntransfer now pins the first child run instead of the latest, so later follow-ups do not replace the delegated run identity.subagent_resulttransfer lookup prefers transfers whosesourcePoint.runIdmatches the run, with a legacy fallback when the delegated run has no run id on the transfer.Contracts, MCP tool descriptions, orchestration docs, and integration tests were updated for the new result shape and wait-mode documentation (wait blocks on the original delegated run).
Reviewed by Cursor Bugbot for commit b73f59d. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Expose pending delegated child work and latest terminal run details in
readTaskhasPendingChildRunsandlatestTerminal*fields (latestTerminalRunId,latestTerminalStatus,latestTerminalSummary,latestTerminalResultContextTransferId) to theOrchestratorMcpDelegateTaskResultcontract andreadTaskresponse.hasPendingChildRuns,latestTerminalResultRun, andcanExposeTaskRunResulthelpers inOrchestratorMcpServiceto identify queued/running follow-up child runs and the highest-ordinal meaningful terminal run.subagent_spawntransfer) now returnschildProjection.runs[0](earliest run) instead oflatestRun(childProjection).Macroscope summarized e95b1be.